home *** CD-ROM | disk | FTP | other *** search
/ Chaos CD Blue / Chaos_CD_Blue__[1999].iso / ds / 41 / pocsac.c < prev    next >
C/C++ Source or Header  |  1999-04-05  |  13KB  |  518 lines

  1. /*
  2. **  Projekt:                SCCD (Simple City-Call Decoder)
  3. **  Modul:                  pocsac.c
  4. **  Abhaengige module:      none
  5. **  Copyright:              gone
  6. **  Version:                kappa 1.3E-15 (standallone COM1)
  7. **  Lastmodification:         15.11.92 19:38
  8. **  History:
  9. **
  10. **
  11. ** f1 = 465.970 MHz     512 Bits/sec
  12. ** f2 = 466.075 MHz     1200 Bits/sec
  13. ** f3 = 466.230 MHz     1200 Bits/sec
  14. **
  15. */
  16.  
  17.  
  18. /* compact memory model */
  19. /* keine flotingpoint emu */
  20. /* nested comments */
  21.  
  22. /*
  23. **
  24. ** Includes fuer dieses Modul
  25. **
  26. */
  27. #include <stdio.h>
  28. #include <io.h>
  29. #include <dos.h>
  30. #include <fcntl.h>
  31. #include <alloc.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <conio.h>
  35. #include <time.h>
  36.  
  37.  
  38. /*
  39. **
  40. ** Defines die die arbeitsweise beeinflussen
  41. **
  42. */
  43. #define BITWRONG                /* fallback wenn paritaet nicht stimmt */
  44. #define LOGFILE                    /* Wir schreiben eine Logfile fuer
  45.                                    spaetere Datenbankauswertungen */
  46.  
  47.  
  48. /*
  49. **
  50. ** Defines fuer dieses Modul
  51. **
  52. */
  53. #define TIMER0CLOCK 1193182L    /* Grundfreqenz des Timerbausteins */
  54.                                 /* divisor für timer 0 : sample
  55.                                    time=30/CLOCK_FREQ = 25.1 uSec */
  56. #define TIMER0B512  2330          /* Teilerrate fuer 512 Baud */
  57. #define TIMER0B1200 994            /* Teilerrate fuer 1200 Baud */
  58.  
  59. #define MAXARRAY 60000            /* groesse des bitpuffers */
  60.  
  61. #define SYNCRON  0x7cd215d8L    /* Frame fuer das Syncronwort */
  62. #define SYNCINFO 0x7cd21436L    /* Frame fuer das InforufSyncronwort */
  63. #define IDLE     0x7a89c197L    /* Frame fuer das Idlewort */
  64.  
  65. #define COMPORT    0x3f8           /* alles fuer COM1 */
  66. #define TXBYTE  0
  67. #define RXBYTE  0
  68. #define DIFLLB  0
  69. #define DIFLHB  1
  70. #define IER     1
  71. #define IIR        2
  72. #define LCR        3
  73. #define MCR        4
  74. #define LSR        5
  75. #define MSR        6
  76.  
  77.  
  78. #define GETSYNCR     1            /* Auf erstes Syncronwort warten */
  79. #define GETFRAME    2            /* Frames einladen */
  80.  
  81.  
  82. /*
  83. **
  84. ** Variablen / Speicher der von diesem Modul benutzt wird
  85. **
  86. */
  87.          char *roh_daten_feld;                /* zeiger auf pufferfeld */
  88. volatile unsigned int  roh_daten_anfang;     /* momentaner Anfang des
  89.                                                Ringpuffers */
  90. volatile unsigned int  roh_daten_ende;        /* momentanes Ende des
  91.                                                Ringpuffers */
  92. volatile unsigned int  roh_daten_laenge;     /* momentane Ringpufferlaenge
  93.                                                (anzahl der Daten) */
  94.  
  95. unsigned int tics;                /* soviel Teilerschritte treten pro Bit
  96.                                    auf */
  97. unsigned int tics_2;            /* die Haelfte der Schritte */
  98.  
  99. void interrupt (*old_vec)();    /* Adresse der alten Timerseviceroutine */
  100. void interrupt (*time_int)();    /* Adresse der alten Timer0 Routine */
  101. void interrupt time_i();        /* prototyp der Timer0 Routine */
  102. void interrupt lauf_er();        /* prototyp der bitholroutine */
  103. volatile int abbruch = 0;        /* wir sollen das Programm verlassen */
  104. volatile int eine_sek_weg = 0;    /* es ist eine Sekunde vergangen */
  105.  
  106. #ifdef LOGFILE
  107. FILE *logfile = NULL;            /* logfile fuer die daten */
  108. volatile int last_sync;            /* Sekunden zaehlen wann das letzte
  109.                                    mal ein Sync emfangen wurde */
  110. #endif
  111.  
  112. char asc_time[40] = "Keine Zeit angegeben";
  113.  
  114. static char numerik[] = {       /* Decodierrung von Numerikpagern */
  115. '0',
  116. '8',
  117. '4',
  118. ' ',
  119. '2',
  120. '=',
  121. '6',
  122. ']',
  123. '1',
  124. '9',
  125. '5',
  126. '_',
  127. '3',
  128. 'U',
  129. '7',
  130. '['
  131. };
  132.  
  133.  
  134. /*
  135. **
  136. ** Routinen dieses Moduls
  137. **
  138. */
  139.  
  140.  
  141. char *
  142. strip_cr(char *cptr)                    /* CR+LF rausscheissen */
  143. {
  144.     char *oldcptr;
  145.  
  146.     oldcptr = cptr;
  147.     while (*cptr != '\0') {
  148.         if (*cptr == '\r' ||  *cptr == '\n')   *cptr = '\0';
  149.         cptr++;
  150.     }
  151.     return(oldcptr);
  152. }
  153.  
  154.  
  155. #define ADRESS 0                /* Wir haben eine Adresse */
  156. #define DATEN  1                /* Wir haben Daten */
  157.  
  158. void
  159. decode_frame(int framepos, unsigned long frame)    /* Ein emfangenes Frame
  160.                                                    entschluesseln */
  161. {
  162. static unsigned long lastadress = 0L;    /* letzte emfaenger adresse */
  163. static int lastadrfunktion = 0;            /* letzte funktion der adresse */
  164. static char lastchar = '\0';
  165. static int lastbitpos = 0;                /* letzte Frameposition */
  166. static int lastget = ADRESS;            /* was fuer einen Typ hatte das
  167.                                            letzte Frame ? */
  168.  
  169.     int i;
  170.     unsigned long l;
  171.  
  172.  
  173.     if ((frame&0x80000000) != 0L)   i = 1;      /* nachricht */
  174.     else   i = 0;                                /* adresse (nur Ton) */
  175.     if (i == 0) {                                /* es ist ein adress
  176.                                                    frame */
  177.  
  178.         if (lastget == ADRESS  &&  lastadrfunktion > 0  && \
  179.             lastadress != 0) {    /* der letzte war eine adresse also
  180.                                    war er nurton */
  181.  
  182.             printf("\nA:%07ld | %s | T | BEEP", lastadress, asc_time);
  183.             printf("%d", lastadrfunktion);
  184. #ifdef LOGFILE
  185.             fprintf(logfile, "\nA:%07ld | %s | T | BEEP", lastadress, \
  186.                 asc_time);
  187.             fprintf(logfile, "%d", lastadrfunktion);
  188. #endif
  189.         }
  190.  
  191.         if (frame == SYNCRON) {         /* das ist nur ein eingeschobenes
  192.                                            Syncronwort */
  193.             lastget = DATEN;            /* wird nicht als adresse
  194.                                            gewertet */
  195.         } else if (frame == IDLE) {        /* das ist nur ein Fuellwort */
  196.             lastadress = 0L;
  197.             lastadrfunktion = 0;        /* alles zurueckstellen */
  198.             lastbitpos = 0;
  199.             lastget = ADRESS;            /* ende einer Nachricht */
  200.         } else {                          /* adressse + funktion merken */
  201.             lastadress = ((frame>>10)&0x001FFFF8L)+(framepos/2);
  202.             lastadrfunktion = ((frame >> 11)&0x00000003L)+1;
  203.             lastbitpos = 0;
  204.             lastget = ADRESS;            /* dies war eine Adresse */
  205.         }
  206.     } else {                            /* es ist ein Daten frame */
  207.  
  208.         if (lastbitpos == 0) {            /* wir sind am anfang eines
  209.                                            Datenwortes */
  210.             if (lastadrfunktion == 1) {    /* numerikpager */
  211.                 printf("\nA:%07ld | %s | N | ", lastadress, asc_time);
  212. #ifdef LOGFILE
  213.                 fprintf(logfile, "\nA:%07ld | %s | N | ", lastadress, \
  214.                     asc_time);
  215. #endif
  216.             } else if (lastadrfunktion == 4) {    /* alphaPager */
  217.                 printf("\nA:%07ld | %s | A | ", lastadress, asc_time);
  218. #ifdef LOGFILE
  219.                 fprintf(logfile, "\nA:%07ld | %s | A | ", lastadress, \
  220.                     asc_time);
  221. #endif
  222.                 lastchar = '\0';
  223.             }
  224.         }
  225.  
  226.  
  227.  
  228.         /* Daten analysiern und ausgeben */
  229.         frame <<= 1;                    /* das erste bit wurde schon
  230.                                            interpretiert und wird jetzt
  231.                                            ignoriert */
  232.         i = 0;
  233.         if (lastadrfunktion == 1) {        /* numerik Pager decodieren */
  234.             for (i = 0; i <= 4; i++) {
  235.                 l = frame&0xf0000000L;    /* ich brauch nur die
  236.                                            hoechsten vier bits */
  237.                 l >>= 28;                /* bitte als char */
  238.                 printf("%c", numerik[(char)l]);    /* so einer sind wir */
  239. #ifdef LOGFILE
  240.                 fprintf(logfile, "%c", numerik[(char)l]);
  241. #endif
  242.                 frame <<= 4;
  243.                 lastbitpos += 4;
  244.             }
  245.         }
  246.         if (lastadrfunktion == 4) {        /* alpha Pager decodieren */
  247.             for (i = 0; i <= 19; i++) {    /* alle 20 Bits nacheinader
  248.                                            durchmachen */
  249.                 lastchar >>= 1;
  250.                 if ((frame&0x80000000L) != 0L)   lastchar |= 0x40; /* bit in ein Char schieben */
  251.                 frame <<= 1;
  252.                 lastbitpos++;
  253.                 if ((lastbitpos%7) == 0) {        /* ein neues Datenwort
  254.                                                    ist voll */
  255.                     printf("%c", lastchar);
  256. #ifdef LOGFILE
  257.                     fprintf(logfile, "%c", lastchar);
  258. #endif
  259.                     lastchar = '\0';
  260.                 }
  261.             }
  262.         }
  263.         lastget = DATEN;
  264.     }
  265. }
  266.  
  267.  
  268. void
  269. mach_hin(int baud)                /* wir gehen auf emfang */
  270. {
  271.     int i, j, k, anz, paritaet, timercl, timertic;
  272.     unsigned long l;
  273.     int getmodus;
  274.     char old_0x21, old_pio_b;
  275.     char c;
  276.     time_t zeit;
  277.     struct tm *zeit2;
  278.  
  279. #ifdef LOGFILE
  280.     logfile = fopen("logfile.txt", "a");
  281.     if (logfile == NULL)   return;
  282. #endif
  283.  
  284.  
  285.     disable();                    /* alle interrupts abschalten */
  286.  
  287.     roh_daten_anfang = roh_daten_ende = roh_daten_laenge = 0;
  288.     getmodus = GETSYNCR;
  289.     anz = k = 0;
  290.     if (baud == 1200) {
  291.         printf("1200 Baud\n");
  292.         tics = TIMER0B1200;
  293.     } else {
  294.         printf("512 Baud\n");
  295.         tics = TIMER0B512;
  296.     }
  297.     tics_2 = tics/2;
  298.  
  299.     old_vec = getvect(12);        /* alte Timerserviceroutine retten */
  300.     setvect(12, lauf_er);        /* timerserviceroutine setzen */
  301.  
  302.     time_int = getvect(0x1c);    /* timer0 interrupt setzen */
  303.     setvect(0x1c, time_i);
  304.  
  305.     outportb(COMPORT+MCR, 0x09);/* Leitungen setzen */
  306.     outportb(COMPORT+IER, 0x08);/* MODEMzustandswechsel */
  307.  
  308.     old_0x21 = inportb(0x21);    /* interrupt maske holen */
  309.     outportb(0x21, old_0x21&(char)(~((char)0x10)));        /* Timer 2
  310.                                                            einschalten */
  311.  
  312.     outportb(0x43, 0xB0);        /* Zaehler auf hoechsten wert stellen */
  313.     outportb(0x42, 0xff);
  314.     outportb(0x42, 0xff);
  315.     old_pio_b = inportb(0x61);            /* pio-b einlesen */
  316.     outportb(0x61, old_pio_b|0x01);        /* Zaehler einschalten */
  317.  
  318.     enable();                    /* jetzt gehts los  */
  319.  
  320.  
  321.  
  322.     do {
  323.         if (abbruch)   break;
  324.  
  325.  
  326.         if (eine_sek_weg) {                /* uhr nachstellen */
  327.             eine_sek_weg = 0;
  328.  
  329.             if (kbhit() != 0) {            /* ein Zeichen von der Tastatur
  330.                                            liegt an also abbrechen */
  331.                 break;
  332.             }
  333.  
  334.             time(&zeit);
  335.             zeit2 = localtime(&zeit);
  336.             strcpy(asc_time, strip_cr(asctime(zeit2)));    /* neue uhrzeit */
  337.  
  338. #ifdef LOGFILE
  339.             if (last_sync >= 0)   last_sync++;
  340.             if (last_sync > 20) {    /* 20 Sekunden lang kein Sync mehr
  341.                                        gekommen */
  342.                 disable();
  343.                 if (logfile != NULL)   fclose(logfile);
  344.                 logfile = fopen("logfile.txt", "a");
  345.                 if (logfile == NULL) {
  346.                     printf("Logfile laesst sich nicht oeffnen\n");
  347.                     abbruch = 1;
  348.                 }
  349.                 enable();
  350.                 last_sync = -1;
  351.             }
  352. #endif
  353.         }
  354.  
  355.  
  356.         if (roh_daten_laenge > 0) {        /* timerinterrupt hat ein oder
  357.                                            mehr neue Zeichen eingelesen */
  358.  
  359.             /* felddaten holen */
  360.             i = roh_daten_feld[roh_daten_anfang++];
  361.             if (roh_daten_anfang > MAXARRAY)   roh_daten_anfang = 0;
  362.             roh_daten_laenge--;
  363. /*
  364.             printf("%c", i+'0');
  365.             fflush(stdout);
  366. */
  367.             /* felddaten auswerten */
  368.  
  369.             if (getmodus == GETSYNCR) {        /* Erstes Syncronframe
  370.                                                erwarten */
  371.                 l <<= 1;
  372.                 if (i == 1)   l |= 0x00000001L;            /* bit setzen */
  373.                 if (l == SYNCRON  ||  l == SYNCINFO) {    /* wert stimmt
  374.                                                         mit Syncronwort
  375.                                                         ueberein */
  376. /*                    printf("\nSyncronwort");
  377.                     fflush(stdout);                       */
  378.                     last_sync = 0;
  379.                     getmodus = GETFRAME;
  380.                     anz = k = paritaet = 0;
  381.                     l = 0L;
  382.                     decode_frame(0, IDLE);
  383.                 }
  384.             } else if (getmodus == GETFRAME) {    /* GETFRAME Daten als
  385.                                                    Frame einlesen */
  386.                 anz++;
  387.                 l <<= 1;
  388.                 if (i == 1) {
  389.                     l |= 0x00000001L;             /* bit setzen */
  390.                     if (paritaet == 0)   paritaet = 1;
  391.                     else   paritaet = 0;
  392.                 }
  393.                 if (anz >= 32) {                /* neues Frame ist
  394.                                                    vollstaendig */
  395.                     if (paritaet == 1) {
  396.                         printf("%c", 247);        /* paritaetsfehler */
  397.                         fflush(stdout);
  398. #ifdef BITWRONG
  399.                         l = 1L;                    /* fallback machen */
  400.                         getmodus = GETSYNCR;
  401.                         decode_frame(0, IDLE);
  402.                         anz = k = paritaet = 0;
  403. #endif
  404.                     }
  405.                     if (k >= 16  ||  l == SYNCRON  ||  l == SYNCINFO) {
  406.                         /* egal was dies MUSS ein Syncronwort seien */
  407.                         decode_frame(0, SYNCRON);
  408.                         last_sync = 0;
  409.                         k = 0;
  410.                     } else if (l == IDLE) {     /* nur idle keine
  411.                                                    relevanten daten */
  412.                         decode_frame(k, l);
  413. /*                        printf("IDLE\n"); */
  414.                         k++;
  415.                     } else {                    /* endlich ein
  416.                                                    normales Frame */
  417.                         decode_frame(k, l);
  418.                         k++;
  419.                     }
  420.                     anz = paritaet = 0;
  421.                     l = 0L;
  422.                 }
  423.             }
  424.         }
  425.  
  426.  
  427.     } while(42);                /* endlos */
  428.  
  429.  
  430.  
  431.     /* destall interrupts */
  432.     disable();
  433.     setvect(12, old_vec);        /* timerserviceroutine zuruecksetzen */
  434.     setvect(0x1c, time_int);    /* alter Timer2 interrupt */
  435.     outportb(0x21, old_0x21);    /* alte Timer einschalten */
  436.     outportb(0x61, old_pio_b);    /* Zaehler Ursprung */
  437.     enable();
  438. #ifdef LOGFILE
  439.     if (logfile != NULL)           fclose(logfile);
  440. #endif
  441.     return;
  442. }
  443.  
  444.  
  445. void
  446. interrupt lauf_er()                /* interrupt wenn wechsel an CTS
  447.                                    verstrichene Zeit und Zustand
  448.                                    feststellen, anzahl von 0/1 in
  449.                                    puffer schreiben */
  450. {
  451.     char bytein, c;
  452.     unsigned int i;
  453.     unsigned int j;
  454.  
  455.  
  456.     bytein = inportb(COMPORT+MSR);
  457.     if ((bytein&0x01) == 0x01) {    /* CTS zustands wechselaufgetreten */
  458.         c = ((bytein&0x10) != 0) ? (char)0 : (char)1; /* hab ich ne 0
  459.                                                          oder ne 1 */
  460.         outportb(0x43, 0x80);        /* Zaehlerstand auslesen */
  461.         i = inportb(0x42);
  462.         i += (256 * inportb(0x42));
  463.         outportb(0x43, 0xB0);        /* Zaehler auf hoechsten wert neustellen */
  464.         outportb(0x42, 0xff);
  465.         outportb(0x42, 0xff);
  466.  
  467.         i = 0xffff-i;                /* wieviele Zaehlerschritte sind
  468.                                        vergangen */
  469.         j = i/tics;                 /* wieviele Bits waehren das ? */
  470.         if (i%tics > tics_2)  j++;  /* ist vieleicht die Zeit
  471.                                        unterlaufen worden? */
  472. /*    if (j <= 0)  j = 1; */
  473.  
  474.         for (i = 1; i <= j; i++) {    /* anzahl der bits die decodiert
  475.                                        wurden speichern */
  476.             if (roh_daten_laenge < MAXARRAY) {
  477.                 roh_daten_feld[roh_daten_ende++] = c;
  478.                 if (roh_daten_ende > MAXARRAY)   roh_daten_ende = 0;
  479.                 roh_daten_laenge++;
  480.             } else   printf("\nPufferueberlauf\n");
  481.         }
  482.     }
  483.     outportb(0x20,0x20);            /* end of interrupt klarmachen */
  484. }
  485.  
  486.  
  487. void interrupt time_i()                /* wird 18.2/Sekunde aufgerufen */
  488. {
  489. static int t = 0;
  490.  
  491.     t++;
  492.     if (t >= 19) {    /* genuegend zeit vergangen ? */
  493.         t = 0;
  494.         eine_sek_weg = 1;
  495.     }
  496. /*    time_int();    */    /* alte zeitroutine weiter machen */
  497. }
  498.  
  499.  
  500.  
  501. int
  502. main(int argc, char *argv[])
  503. {
  504.     roh_daten_feld = (char *)malloc(MAXARRAY+300);
  505.     if (roh_daten_feld == NULL)   exit(0);
  506.     printf("\nPOCSAC Decoder fuer COM1\n");
  507.     printf("Als Argumente bitte die Baudrate eingeben (512/1200)\n");
  508.     if (argc != 2) {
  509.         printf("keine Baudrate\n");
  510.         return(0);
  511.     }
  512.  
  513.     mach_hin(atoi(argv[1]));
  514.  
  515.     free(roh_daten_feld);
  516. }
  517.  
  518.